package com.ulife.order.components.core.cancel;

import com.alibaba.dubbo.common.logger.Logger;
import com.alibaba.dubbo.common.logger.LoggerFactory;
import com.alibaba.dubbo.config.annotation.Reference;
import com.google.common.base.Strings;
import com.ulife.base.entities.order.SaleOrder;
import com.ulife.base.entities.order.SaleOrderPay;
import com.ulife.base.entities.order.SoCancelBill;
import com.ulife.base.entities.order.SoCancelBillCriteria;
import com.ulife.base.logics.order.SaleOrderLogic;
import com.ulife.base.logics.order.SoCancelBillLogic;
import com.ulife.common.gateway.utils.define.Version;
import com.ulife.common.utils.lang.JsonMapper;
import com.ulife.common.utils.lang.StringUtils;
import com.ulife.member.api.MemberService;
import com.ulife.order.api.core.cancel.CancelBillStatus;
import com.ulife.order.api.core.refund.OperationType;
import com.ulife.order.api.core.refund.RefundBillStatus;
import com.ulife.order.api.core.refund.RefundWay;
import com.ulife.order.api.errors.OrderErrorCodes;
import com.ulife.order.components.core.pay.OrderPay;
import com.ulife.order.components.core.result.BaseResult;
import com.ulife.order.components.core.result.ResultCode;
import com.ulife.order.service.domain.Order;
import com.ulife.order.components.core.refund.OrderRefund;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;


/**
 * Created by Lbq on 2016/05/24.
 */
@Component
public class OrderCancel {
    private static JsonMapper Json = JsonMapper.nonDefaultMapper();
    Logger logger = LoggerFactory.getLogger(Order.class);

    @Resource
    SoCancelBillLogic soCancelBillLogic;

    @Resource
    SaleOrderLogic saleOrderLogic;

    @Resource
    OrderPay orderPay;

    @Resource
    OrderRefund orderRefund;

    @Reference(version = Version.LATEST)
    MemberService memberService;

    /**
     * 处理 取消订单单据
     * @param soCancelBill
     * @return
     */
    public BaseResult ProcessSoCancelBill(SoCancelBill soCancelBill,long operator) {
        //生成退款单
        return ProcessSoCancelBill(soCancelBill, OperationType.Manual
                , RefundWay.PayWayRefund, null, operator);
    }

    /**
     * 处理 取消订单单据
     * @param soCancelBill
     * @param operationType
     * @param refundWay
     * @param refundChannel
     * @return
     */
    public BaseResult ProcessSoCancelBill(SoCancelBill soCancelBill
            ,OperationType operationType
            ,RefundWay refundWay, String refundChannel,long operator) {

        BaseResult result = new BaseResult();
        if (soCancelBill.getStatus() != CancelBillStatus.Created.value()) {
            result.setMessage("订单取消单据状态不正确");
            return result;
        }
        List<SaleOrderPay> saleOrderPays = orderPay.getListBySoNo(soCancelBill.getSoNo());
        try {
            //是否需要生成退款单 0.创建退款单失败 1.生成了退款单 2.不需要生成退款单
            int rtn = SoCancelBillToRefund(soCancelBill,saleOrderPays,operationType,refundWay,refundChannel,operator);
            switch (rtn){
                case 0:
                    result.setMessage("处理订单取消单据：".concat(soCancelBill.getSoNo()).concat("，创建退款单失败！"));
                    break;
                case 1:
                case 2:
                    //更新单据状态
                    soCancelBill.setStatus(CancelBillStatus.Finished.value());
                    soCancelBillLogic.updateSelective(soCancelBill);
                    break;
            }
            if(rtn > 0) result.setCode(ResultCode.Success);
        }catch (Exception ex){
            result.setMessage("处理订单取消单据：".concat(soCancelBill.getSoNo()).concat(ex.getMessage()));
        }
        return result;
    }

    /**
     * 根据取消单 生成退款单
     * @param soCancelBill
     * @param saleOrderPays
     * @param operationType
     * @param refundWay
     * @param refundChannel
     * @return 是否需要生成退款单 0.创建退款单失败 1.生成了退款单 2.不需要生成退款单
     */
    private int SoCancelBillToRefund(SoCancelBill soCancelBill,List<SaleOrderPay> saleOrderPays
            ,OperationType operationType
            ,RefundWay refundWay, String refundChannel,long operator) throws Exception{

        if(soCancelBill.getIsNeedRefund() == 0 || saleOrderPays == null || saleOrderPays.size() == 0){
            return 2;
        }
        if(!orderRefund.batchCreateSoRefundBill(saleOrderPays, operationType, refundWay, refundChannel,operator)){
            return 0;
        }
        return 1;
    }


    /***
     * 创建取消订单单据
     * @param saleOrder
     * @param modified_by
     * @param operationType
     * @param cancelType
     * @param cancelReason
     * @param cancelRemark
     * @param isNeedRefund
     * @return
     */
    public boolean createSoCancelBilll(SaleOrder saleOrder, long modified_by, int operationType, String cancelType, String cancelReason, String cancelRemark, int isNeedRefund) {
        try {
            SoCancelBill soCancelBill=new SoCancelBill();
            soCancelBill.setCancelBillNo(getCancelBillNo());
            soCancelBill.setOperationType(operationType);
            soCancelBill.setSoNo(saleOrder.getSaleNo());
            soCancelBill.setOrderOriginalStatus(saleOrder.getStatus());
            soCancelBill.setPayChannel(saleOrder.getPayChannel());
            soCancelBill.setPayStatus(saleOrder.getPayStatus());
            soCancelBill.setCancelType(cancelType);
            soCancelBill.setCancelReason(cancelReason);
            soCancelBill.setCancelRemark(cancelRemark);
            soCancelBill.setIsNeedRefund(isNeedRefund);
            soCancelBill.setStatus(CancelBillStatus.Created.value());
            soCancelBill.setIsDelete(1);
            soCancelBill.setCreator(modified_by);
            soCancelBill.setCreateTime(new Date());
            soCancelBill.setModifier(modified_by);
            soCancelBill.setModifyTime(new Date());
            //transaction
            if(soCancelBillLogic.insert(soCancelBill) == 1) return true;

        } catch (Exception ex) {
            logger.error("创建取消单:".concat(ex.getMessage()));
            return false;
        }
        return false;
    }

    /**
     * 生成取消单号
     * @return
     * @throws Exception
     */
    private String getCancelBillNo() throws Exception {
        String generateOrderNo = "";
        String fix="RCN";
        try {
            generateOrderNo=memberService.generateOrderNo();
            if(Strings.isNullOrEmpty(generateOrderNo)){
                throw new Exception("【会员服务|生成订单号 in 生成取消单据方法】 报错");
            }
        }catch (Exception ex)
        {
            logger.error("【会员服务|生成订单号 in 生成取消单据方法】 报错");
            logger.error(ex);
            throw new Exception("【会员服务|生成订单号 in 生成取消单据方法】 报错");
        }
        return  fix+generateOrderNo;
    }

}
